Source for file GD.php

Documentation is available at GD.php

  1. <?php
  2. /***********************************************************************
  3. ** Title.........:  GD Driver
  4. ** Version.......:  1.0
  5. ** Author........:  Xiang Wei ZHUO <wei@zhuo.org>
  6. ** Filename......:  GD.php
  7. ** Last changed..:  30 Aug 2003 
  8. ** Notes.........:  Orginal is from PEAR
  9. **/
  10. // +----------------------------------------------------------------------+
  11. // | PHP Version 4                                                        |
  12. // +----------------------------------------------------------------------+
  13. // | Copyright (c) 1997-2002 The PHP Group                                |
  14. // +----------------------------------------------------------------------+
  15. // | This source file is subject to version 2.02 of the PHP license,      |
  16. // | that is bundled with this package in the file LICENSE, and is        |
  17. // | available at through the world-wide-web at                           |
  18. // | http://www.php.net/license/2_02.txt.                                 |
  19. // | If you did not receive a copy of the PHP license and are unable to   |
  20. // | obtain it through the world-wide-web, please send a note to          |
  21. // | license@php.net so we can mail you a copy immediately.               |
  22. // +----------------------------------------------------------------------+
  23. // | Authors: Peter Bowyer <peter@mapledesign.co.uk>                      |
  24. // |          Alan Knowles <alan@akbkhome.com>                            |
  25. // +----------------------------------------------------------------------+
  26. //
  27. //    Usage :
  28. //    $img    = new Image_Transform_GD();
  29. //    $angle  = -78;
  30. //    $img->load('magick.png');
  31. //
  32. //    if($img->rotate($angle,array('autoresize'=>true,'color_mask'=>array(255,0,0)))){
  33. //        $img->addText(array('text'=>"Rotation $angle",'x'=>0,'y'=>100,'font'=>'/usr/share/fonts/default/TrueType/cogb____.ttf'));
  34. //        $img->display();
  35. //    } else {
  36. //        echo "Error";
  37. //    }
  38. //
  39. //
  40. // $Id$
  41. //
  42. // Image Transformation interface using the GD library
  43. //
  44.  
  45. require_once "Transform.php";
  46.  
  47. {
  48.     /**
  49.      * Holds the image file for manipulation
  50.      */
  51.     var $imageHandle = '';
  52.  
  53.     /**
  54.      * Holds the original image file
  55.      */
  56.     var $old_image = '';
  57.  
  58.     /**
  59.      * Check settings
  60.      *
  61.      * @return mixed true or  or a PEAR error object on error
  62.      *
  63.      * @see PEAR::isError()
  64.      */
  65.     function Image_Transform_GD()
  66.     {
  67.         return;
  68.     // End function Image
  69.  
  70.     /**
  71.      * Load image
  72.      *
  73.      * @param string filename
  74.      *
  75.      * @return mixed none or a PEAR error object on error
  76.      * @see PEAR::isError()
  77.      */
  78.     function load($image)
  79.     {
  80.         $this->uid md5($_SERVER['REMOTE_ADDR']);
  81.         $this->image $image;
  82.         $this->_get_image_details($image);
  83.         $functionName 'ImageCreateFrom' $this->type;
  84.         if(function_exists($functionName))
  85.         {
  86.             $this->imageHandle = $functionName($this->image);
  87.         }
  88.     // End load
  89.  
  90.     /**
  91.      * addText
  92.      *
  93.      * @param   array   options     Array contains options
  94.      *                               array(
  95.      *                                   'text'  The string to draw
  96.      *                                   'x'     Horizontal position
  97.      *                                   'y'     Vertical Position
  98.      *                                   'Color' Font color
  99.      *                                   'font'  Font to be used
  100.      *                                   'size'  Size of the fonts in pixel
  101.      *                                   'resize_first'  Tell if the image has to be resized
  102.      *                                                   before drawing the text
  103.      *                               )
  104.      *
  105.      * @return none 
  106.      * @see PEAR::isError()
  107.      */
  108.     function addText($params)
  109.     {
  110.         $default_params array(
  111.                                 'text' => 'This is Text',
  112.                                 'x' => 10,
  113.                                 'y' => 20,
  114.                                 'color' => array(255,0,0),
  115.                                 'font' => 'Arial.ttf',
  116.                                 'size' => '12',
  117.                                 'angle' => 0,
  118.                                 'resize_first' => false // Carry out the scaling of the image before annotation?  Not used for GD
  119.                                 );
  120.         $params array_merge($default_params$params);
  121.         extract($params);
  122.  
  123.         if!is_array($color) ){
  124.             if ($color[0]=='#'){
  125.                 $this->colorhex2colorarray$color );
  126.             else {
  127.                 include_once('Image/Transform/Driver/ColorsDefs.php');
  128.                 $color = isset($colornames[$color])?$colornames[$color]:false;
  129.             }
  130.         }
  131.  
  132.         $c imagecolorresolve ($this->imageHandle$color[0]$color[1]$color[2]);
  133.  
  134.         if ('ttf' == substr($font-3)) {
  135.             ImageTTFText($this->imageHandle$size$angle$x$y$c$font$text);
  136.         else {
  137.             ImagePSText($this->imageHandle$size$angle$x$y$c$font$text);
  138.         }
  139.         return true;
  140.     // End addText
  141.  
  142.  
  143.     /**
  144.      * Rotate image by the given angle
  145.      * Uses a fast rotation algorythm for custom angles
  146.      * or lines copy for multiple of 90 degrees
  147.      *
  148.      * @param int       $angle      Rotation angle
  149.      * @param array     $options    array(  'autoresize'=>true|false,
  150.      *                                       'color_mask'=>array(r,g,b), named color or #rrggbb
  151.      *                                    )
  152.      * @author Pierre-Alain Joye
  153.      * @return mixed none or a PEAR error object on error
  154.      * @see PEAR::isError()
  155.      */
  156.     function rotate($angle$options=null)
  157.     {
  158.         if(function_exists('imagerotate'&& false{
  159.             $white imagecolorallocate ($this->imageHandle255255255);
  160.             $this->imageHandle = imagerotate($this->imageHandle$angle$white);
  161.             return true;
  162.         }
  163.  
  164.         if $options==null ){
  165.             $autoresize true;
  166.             $color_mask array(255,255,0);
  167.         else {
  168.             extract$options );
  169.         }
  170.  
  171.         while ($angle <= -45{
  172.             $angle  += 360;
  173.         }
  174.         while ($angle 270{
  175.             $angle  -= 360;
  176.         }
  177.  
  178.         $t      deg2rad($angle);
  179.  
  180.         if!is_array($color_mask) ){
  181.             if ($color[0]=='#'){
  182.                 $this->colorhex2colorarray$color_mask );
  183.             else {
  184.                 include_once('Image/Transform/Driver/ColorDefs.php');
  185.                 $color = isset($colornames[$color_mask])?$colornames[$color_mask]:false;
  186.             }
  187.         }
  188.  
  189.         // Do not round it, too much lost of quality
  190.         $cosT   cos($t);
  191.         $sinT   sin($t);
  192.  
  193.         $img    =$this->imageHandle;
  194.  
  195.         $width  $max_x  $this->img_x;
  196.         $height $max_y  $this->img_y;
  197.         $min_y  0;
  198.         $min_x  0;
  199.  
  200.         $x1     round($max_x/2,0);
  201.         $y1     round($max_y/2,0);
  202.  
  203.         if $autoresize ){
  204.             $t      abs($t);
  205.             $a      round($angle,0);
  206.             switch((int)($angle)){
  207.                 case 0:
  208.                         $width2     $width;
  209.                         $height2    $height;
  210.                     break;
  211.                 case 90:
  212.                         $width2     $height;
  213.                         $height2    $width;
  214.                     break;
  215.                 case 180:
  216.                         $width2     $width;
  217.                         $height2    $height;
  218.                     break;
  219.                 case 270:
  220.                         $width2     $height;
  221.                         $height2    $width;
  222.                     break;
  223.                 default:
  224.                     $width2     = (int)(abs(sin($t$height cos($t$width));
  225.                     $height2    = (int)(abs(cos($t$height+sin($t$width));
  226.             }
  227.  
  228.             $width2     -= $width2%2;
  229.             $height2    -= $height2%2;
  230.  
  231.             $d_width    abs($width $width2);
  232.             $d_height   abs($height $height2);
  233.             $x_offset   $d_width/2;
  234.             $y_offset   $d_height/2;
  235.             $min_x2     = -abs($x_offset);
  236.             $min_y2     = -abs($y_offset);
  237.             $max_x2     $width2;
  238.             $max_y2     $height2;
  239.         }
  240.  
  241.         if(function_exists('ImageCreateTrueColor')){
  242.             $img2 =ImageCreateTrueColor($width2,$height2);
  243.         else {
  244.             $img2 =ImageCreate($width2,$height2);
  245.         }
  246.     
  247.  
  248.         if !is_resource($img2) ){
  249.             return false;/*PEAR::raiseError('Cannot create buffer for the rotataion.',
  250.                                 null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
  251.         }
  252.  
  253.         $this->img_x $width2;
  254.         $this->img_y $height2;
  255.  
  256.  
  257.         imagepalettecopy($img2,$img);
  258.  
  259.         $mask   imagecolorresolve($img2,$color_mask[0],$color_mask[1],$color_mask[2]);
  260.  
  261.         // use simple lines copy for axes angles
  262.         switch((int)($angle)){
  263.             case 0:
  264.                 imagefill ($img200,$mask);
  265.                 for ($y=0$y $max_y$y++{
  266.                     for ($x $min_x$x $max_x$x++){
  267.                         $c  @imagecolorat $img$x$y);
  268.                         imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
  269.                     }
  270.                 }
  271.                 break;
  272.             case 90:
  273.                 imagefill ($img200,$mask);
  274.                 for ($x $min_x$x $max_x$x++){
  275.                     for ($y=$min_y$y $max_y$y++{
  276.                         $c  imagecolorat $img$x$y);
  277.                         imagesetpixel($img2,$max_y-$y-1,$x,$c);
  278.                     }
  279.                 }
  280.                 break;
  281.             case 180:
  282.                 imagefill ($img200,$mask);
  283.                 for ($y=0$y $max_y$y++{
  284.                     for ($x $min_x$x $max_x$x++){
  285.                         $c  @imagecolorat $img$x$y);
  286.                         imagesetpixel($img2$max_x2-$x-1$max_y2-$y-1$c);
  287.                     }
  288.                 }
  289.                 break;
  290.             case 270:
  291.                 imagefill ($img200,$mask);
  292.                 for ($y=0$y $max_y$y++{
  293.                     for ($x $max_x$x >= $min_x$x--){
  294.                         $c  @imagecolorat $img$x$y);
  295.                         imagesetpixel($img2,$y,$max_x-$x-1,$c);
  296.                     }
  297.                 }
  298.                 break;
  299.             // simple reverse rotation algo
  300.             default:
  301.                 $i=0;
  302.                 for ($y $min_y2$y $max_y2$y++){
  303.  
  304.                     // Algebra :)
  305.                     $x2 round((($min_x2-$x1$cosT(($y-$y1$sinT $x1),0);
  306.                     $y2 round((($y-$y1$cosT ($min_x2-$x1$sinT $y1),0);
  307.  
  308.                     for ($x $min_x2$x $max_x2$x++){
  309.  
  310.                         // Check if we are out of original bounces, if we are
  311.                         // use the default color mask
  312.                         if $x2>=&& $x2<$max_x && $y2>=&& $y2<$max_y ){
  313.                             $c  imagecolorat $img$x2$y2);
  314.                         else {
  315.                             $c  $mask;
  316.                         }
  317.                         imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
  318.  
  319.                         // round verboten!
  320.                         $x2  += $cosT;
  321.                         $y2  -= $sinT;
  322.                     }
  323.                 }
  324.                 break;
  325.         }
  326.         $this->old_image    = $this->imageHandle;
  327.         $this->imageHandle  =  $img2;
  328.         return true;
  329.     }
  330.  
  331.  
  332.    /**
  333.     * Resize Action
  334.     *
  335.     * For GD 2.01+ the new copyresampled function is used
  336.     * It uses a bicubic interpolation algorithm to get far
  337.     * better result.
  338.     *
  339.     * @param $new_x int  new width
  340.     * @param $new_y int  new height
  341.     *
  342.     * @return true on success or pear error
  343.     * @see PEAR::isError()
  344.     */
  345.     function _resize($new_x$new_y{
  346.         if ($this->resized === true{
  347.             return false/*PEAR::raiseError('You have already resized the image without saving it.  Your previous resizing will be overwritten', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
  348.         }
  349.         if(function_exists('ImageCreateTrueColor')){
  350.             $new_img =ImageCreateTrueColor($new_x,$new_y);
  351.         else {
  352.             $new_img =ImageCreate($new_x,$new_y);
  353.         }
  354.         if(function_exists('ImageCopyResampled')){
  355.             ImageCopyResampled($new_img$this->imageHandle0000$new_x$new_y$this->img_x$this->img_y);
  356.         else {
  357.             ImageCopyResized($new_img$this->imageHandle0000$new_x$new_y$this->img_x$this->img_y);
  358.         }
  359.         $this->old_image = $this->imageHandle;
  360.         $this->imageHandle = $new_img;
  361.         $this->resized true;
  362.  
  363.         $this->new_x $new_x;
  364.         $this->new_y $new_y;
  365.         return true;
  366.     }
  367.  
  368.     /**
  369.      * Crop the image
  370.      *
  371.      * @param int $crop_x left column of the image
  372.      * @param int $crop_y top row of the image
  373.      * @param int $crop_width new cropped image width
  374.      * @param int $crop_height new cropped image height
  375.      */
  376.     function crop($new_x$new_y$new_width$new_height
  377.     {
  378.         if(function_exists('ImageCreateTrueColor')){
  379.             $new_img =ImageCreateTrueColor($new_width,$new_height);
  380.         else {
  381.             $new_img =ImageCreate($new_width,$new_height);
  382.         }
  383.         if(function_exists('ImageCopyResampled')){
  384.             ImageCopyResampled($new_img$this->imageHandle00$new_x$new_y,$new_width,$new_height,$new_width,$new_height);
  385.         else {
  386.             ImageCopyResized($new_img$this->imageHandle00$new_x$new_y$new_width,$new_height,$new_width,$new_height);
  387.         }
  388.         $this->old_image = $this->imageHandle;
  389.         $this->imageHandle = $new_img;
  390.         $this->resized true;
  391.  
  392.         $this->new_x $new_x;
  393.         $this->new_y $new_y;
  394.         return true;
  395.     }
  396.    
  397.     /**
  398.      * Flip the image horizontally or vertically
  399.      *
  400.      * @param boolean $horizontal true if horizontal flip, vertical otherwise
  401.      */
  402.     function flip($horizontal)
  403.     {
  404.         if(!$horizontal{
  405.             $this->rotate(180);
  406.         }
  407.  
  408.         $width imagesx($this->imageHandle)
  409.         $height imagesy($this->imageHandle)
  410.  
  411.         for ($j 0$j $height$j++
  412.                 $left 0
  413.                 $right $width-1
  414.  
  415.  
  416.                 while ($left $right
  417.                     //echo " j:".$j." l:".$left." r:".$right."\n<br>";
  418.                     $t imagecolorat($this->imageHandle$left$j)
  419.                     imagesetpixel($this->imageHandle$left$jimagecolorat($this->imageHandle$right$j))
  420.                     imagesetpixel($this->imageHandle$right$j$t)
  421.                     $left++$right--
  422.                 
  423.             
  424.         }
  425.  
  426.         return true;
  427.     }
  428.  
  429.  
  430.     /**
  431.      * Adjust the image gamma
  432.      *
  433.      * @param float $outputgamma 
  434.      *
  435.      * @return none 
  436.      */
  437.     function gamma($outputgamma=1.0{
  438.         ImageGammaCorrect($this->imageHandle1.0$outputgamma);
  439.     }
  440.  
  441.     /**
  442.      * Save the image file
  443.      *
  444.      * @param $filename string  the name of the file to write to
  445.      * @param $quality  int     output DPI, default is 85
  446.      * @param $types    string  define the output format, default
  447.      *                           is the current used format
  448.      *
  449.      * @return none 
  450.      */
  451.     function save($filename$type ''$quality 85)
  452.     {
  453.         $type           $type==''$this->type $type;
  454.         $functionName   'image' $type;
  455.  
  456.         if(function_exists($functionName))
  457.         {
  458.             $this->old_image = $this->imageHandle;
  459.             if($type=='jpeg')
  460.                 $functionName($this->imageHandle$filename$quality);
  461.             else
  462.                 $functionName($this->imageHandle$filename);
  463.             $this->imageHandle = $this->old_image;
  464.             $this->resized false;
  465.         }
  466.     // End save
  467.  
  468.  
  469.     /**
  470.      * Display image without saving and lose changes
  471.      *
  472.      * @param string type (JPG,PNG...);
  473.      * @param int quality 75
  474.      *
  475.      * @return none 
  476.      */
  477.     function display($type ''$quality 75)
  478.     {
  479.         if ($type != ''{
  480.             $this->type $type;
  481.         }
  482.         $functionName 'Image' $this->type;
  483.         if(function_exists($functionName))
  484.         {
  485.             header('Content-type: image/' strtolower($this->type));
  486.             $functionName($this->imageHandle''$quality);
  487.             $this->imageHandle = $this->old_image;
  488.             $this->resized false;
  489.             ImageDestroy($this->old_image);
  490.             $this->free();
  491.         }
  492.     }
  493.  
  494.     /**
  495.      * Destroy image handle
  496.      *
  497.      * @return none 
  498.      */
  499.     function free()
  500.     {
  501.         if ($this->imageHandle){
  502.             ImageDestroy($this->imageHandle);
  503.         }
  504.     }
  505.  
  506. // End class ImageGD
  507. ?>

Documentation generated on Mon, 05 May 2008 16:19:59 +0400 by phpDocumentor 1.4.0